#!/bin/bash
#
# Copyright 2015-2017 Adrian DC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# === Standalone Source Helper ===
# source <(curl -Ls https://github.com/AdrianDC/android_development_shell_tools/raw/master/android_adb_syncer.rc)

# === ADB Push Sync ===
function adbpushsync()
{
  # Usage
  if [ -z "${1}" ] || [ -z "${2}" ]; then
    echo '';
    echo ' Usage: adbpushsync <local_path> <target_path> (Folders adb push syncer)';
    echo '';
    return;
  fi;

  # Variables
  local cur_path;
  local local_path=${1};
  local remote_path=${2};
  local local_folders;
  local local_files;
  local local_files_ls;
  local line;
  local line_esc;
  local file_size;
  local file_size_loc;

  # Initialize variables
  cur_path=$(pwd);
  local_folders=$(mktemp);
  local_files=$(mktemp);
  local_files_ls=$(mktemp);

  # Access local path
  cd "${local_path}";

  # Header
  echo '';
  echo " adbpushsync: Syncing '${local_path}' to '${remote_path}'";
  echo '';

  # List local folders
  find ./* -type d > "${local_folders}";

  # List target folders
  adb shell "cd '${remote_path}'; find * -type d | sort -r" | while read -r line; do
    echo -en "\r\033[K  Checking folder '${line}'";
    if [ -d "${line}" ]; then
      sed -i "/^${line}/d" "${local_folders}";
    else

      # Delete additional folders
      echo -e "\r\033[K adbpushsync: Deleting target folder '${line}'";
      adb shell "rm -rf \"${remote_path}/${line}\"";

    fi;
  done;

  # Create missing remote folders
  while read -r line; do
    echo -e "\r\033[K adbpushsync: Creating target '${line}'";
    adb shell "mkdir \"${remote_path}/${line}\"";
  done < "${local_folders}";

  # List local files
  find ./* -type f > "${local_files}";
  find ./* -type f -exec ls -l {} \; > "${local_files_ls}";

  # List target files
  adb shell "cd '${remote_path}'; find * -type f" | while read -r line; do
    echo -en "\r\033[K  Checking file '${line}'";
    line_esc=${line//\&/\\\&};
    line_esc=${line_esc//\//\\\/};
    file_size=$(grep "${line}" "${local_files_ls}" 2> /dev/null | cut -d' ' -f2);
    # shellcheck disable=SC2012
    file_size_loc=$(ls -l "${line}" 2> /dev/null | cut -d' ' -f2);
    if [ -e "${line}" ] && [ "${file_size}" -eq "${file_size_loc}" ]; then
      sed -i "/^${line_esc}/d" "${local_files}";
    else

      # Delete additional files
      echo -e "\r\033[K adbpushsync: Deleting target file '${line}' (${file_size} / ${file_size_loc:-Not local})";
      adb shell "rm -rf \"${remote_path}/${line}\"";

    fi;
  done;

  # Push missing remote files
  while read -r line; do
    echo -e "\r\033[K adbpushsync: Pushing to target '${line}'";
    echo -n '  ';
    adb push "${line}" "${remote_path}/${line}";
  done < "${local_files}";

  # Delete temporary files
  rm -f "${local_files}";
  rm -f "${local_files_ls}";
  rm -f "${local_folders}";

  # Restore current path
  cd "${cur_path}";
  echo -e '\r\033[K adbpushsync: Sync done';
  echo '';
}
